package chinatelecom.feilong.framework.web.sys.shiro;


import chinatelecom.feilong.framework.common.security.CredentialsDigest;
import chinatelecom.feilong.framework.common.security.CredentialsMatcherAdapter;
import chinatelecom.feilong.framework.common.util.EndecodeUtils;
import chinatelecom.feilong.framework.web.sys.entity.SysRoleMenuRelation;
import chinatelecom.feilong.framework.web.sys.entity.SysUser;
import chinatelecom.feilong.framework.web.sys.entity.SysUserRoleRelation;
import chinatelecom.feilong.framework.web.sys.service.IUserService;
import chinatelecom.feilong.framework.web.sys.shiro.session.SessionDAO;
import chinatelecom.feilong.framework.web.sys.util.UserUtils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


/**
 * shiro 认证回调realm
 */

@Component("shiroDbRealm")
public class SysAuthorizingDBRealm extends AuthorizingRealm implements InitializingBean{
    
	private Logger log = LoggerFactory.getLogger(SysAuthorizingDBRealm.class);


	@Resource
	protected IUserService userService;

	@Resource
	private CredentialsDigest credentialsDigest;

	@Resource
	private SessionDAO sessionDao;
	
	


	@Override
	public void afterPropertiesSet() throws Exception {
		CredentialsMatcher matcher = new CredentialsMatcherAdapter(
				credentialsDigest);
		setCredentialsMatcher(matcher);
	}

	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		SysUser user = (SysUser) principals.getPrimaryPrincipal();
		Integer userId = user.getId();
		SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
		if (userId != null) {
			//超级管理员
			if (userId==1) {
				auth.addRole("superadmin");
				auth.addStringPermission("*");
			}else{
				//获取当前用户的后台角色
				List<SysUserRoleRelation> urrl = userService.getUserRoleRelationByUserId(userId);
				if(urrl!=null&&urrl.size()>0){
					addPermsToAuth(urrl,auth);
				}
			}
		}
		return auth;
	}

	private void addPermsToAuth(List<SysUserRoleRelation> urrl,SimpleAuthorizationInfo auth){
		SysUserRoleRelation ur = null;
		SysRoleMenuRelation rm = null;
		for(int i=0;i<urrl.size();i++){
			ur = urrl.get(i);
			auth.addRole(ur.getSysRoleByRoleId().getRoleName());
			//获取权限点
			Set<SysRoleMenuRelation> rmrl = ur.getSysRoleByRoleId().getTRoleMenus();
			Iterator<SysRoleMenuRelation> its = rmrl.iterator();
			while(its.hasNext()){
				SysRoleMenuRelation rr = its.next();
				if(StringUtils.isNotBlank(rr.getSysMenuByMenuId().getPermission())){
					auth.addStringPermission(rr.getSysMenuByMenuId().getPermission());
				}

			}
		}
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		LoginToken authToken = (LoginToken)token;
		if(authToken.getLoginType() == 0){
			SysUser user = userService.getByUsername(authToken.getUsername());
			authToken.setData(user);
			// 前后台登录共用，非管理员也可登录。
			if (user != null ) {
				byte[] salt =  EndecodeUtils.decodeHex(user.getConfoundCose());
				return new SimpleAuthenticationInfo(user, user.getPassword(),
						ByteSource.Util.bytes(salt), getName());
			} else {
				return null;
			}
		}else if(authToken.getLoginType() == 1){
			SysUser user= UserUtils.copyToUser((JSONObject) authToken.getData());
			byte[] salt =  EndecodeUtils.decodeHex("37c092ed5dd71ab0");
			return new SimpleAuthenticationInfo(user, "c055854e660a205579fc47be366eb8cf0cc7a639",
					ByteSource.Util.bytes(salt), getName());
		}else{
			return null;
		}

	}



}
